/**
 * 窗口变化监听器
 */
import _ from 'lodash';
import { StateType } from '@/common-typings';

class ResizeObserver {
  // 监听对象
  public isResizing: StateType = {};

  // 事件队列
  public resizeQueue: any[] = [];

  // 懒执行标记
  public lazy: boolean = true;

  // 定时标记
  public timeFlag: any;

  // 执行回掉的时间
  public loopTime: number = 150;

  /**
   * 事件监听器
   * @param event
   */
  listener(event: any) {
    const element = document.documentElement;
    const { body } = document;
    const h = window.innerHeight || (element && element.clientHeight) || body.clientHeight;
    const w = window.innerWidth || (element && element.clientWidth) || body.clientWidth;

    if (!_.isEmpty(this.isResizing) && h === this.isResizing.h && w === this.isResizing.w) {
      console.log('浏览器窗口未改变');
    } else {
      event = event || window.event;

      this.resizeQueue.forEach((item: StateType) => {
        if (item.start && item.cb) {
          if (item.hasOwnProperty('matchHash')) {
            if (item.matchHash && item.id === window.location.pathname) {
              clearTimeout(this.timeFlag);
              this.timeFlag = setTimeout(() => {
                item.cb.call(this, event);
              }, this.loopTime);
            }

            // 其他情况暂时未考虑防抖
          } else {
            item.cb.call(this, event);
          }
        }
      });
      this.isResizing.h = h;
      this.isResizing.w = w;
    }
  }

  /**
   * 添加一次事件监听
   */
  addListener() {
    if (this.lazy) {
      if (window.addEventListener) {
        window.addEventListener('resize', this.listener.bind(this), false);
      } else {
        window.attachEvent('onresize', this.listener.bind(this));
      }
      this.lazy = false;
    }
  }

  /**
   * 添加事件监听任务队列
   * @param id
   * @param cb
   */
  add(id: string, cb: Function) {
    if (id && !this.resizeQueue.filter((item: StateType) => item.id === id).length) {
      this.resizeQueue.push({ id, cb, start: false });
    }
    this.addListener();
    return this;
  }

  /**
   * 移除任务队列
   * @param id
   */
  remove(id: string) {
    this.resizeQueue = this.resizeQueue.filter(item => item.id !== id);
    return this;
  }

  /**
   * 清空任务队列
   */
  clear() {
    this.resizeQueue = [];
  }

  /**
   * 启动指定事件
   * @param id
   */
  start(id: string) {
    this.resizeQueue.forEach((item: StateType) => {
      if (id === item.id) {
        item.start = true;
      }
    });
    return this;
  }

  /**
   * 指定id需要匹配路由
   * @param id
   */
  requireMatchRouter(id: string) {
    this.resizeQueue.forEach((item: StateType) => {
      if (id === item.id) {
        item.matchHash = true;
      }
    });
    return this;
  }

  /**
   * 停止指定事件
   * @param id
   */
  stop(id: string) {
    this.resizeQueue.forEach((item: StateType) => {
      if (id === item.id) {
        item.start = false;
      }
    });
  }

  /**
   * 获取所有任务队列
   */
  getQueue() {
    return this.resizeQueue;
  }

  static instance: any;

  static getInstance() {
    if (!this.instance) {
      this.instance = new ResizeObserver();
    }
    return this.instance;
  }
}

export default ResizeObserver.getInstance();
